package com.hdphone.zljutils.impl;

import android.database.Cursor;
import android.database.sqlite.SQLiteClosable;
import android.util.Log;

import com.hdphone.zljutils.inter.IBeanUtil;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class BeanUtilImpl implements IBeanUtil {
    
    private static final String TAG = "BeanCloneUtilImpl";

    @Override
    public <T> T cloneTo(T src) {
        ByteArrayOutputStream memoryBuffer = new ByteArrayOutputStream();
        ObjectOutputStream out = null;
        ObjectInputStream in = null;
        T dist = null;
        try {
            out = new ObjectOutputStream(memoryBuffer);
            out.writeObject(src);
            out.flush();
            in = new ObjectInputStream(new ByteArrayInputStream(memoryBuffer.toByteArray()));
            dist = (T) in.readObject();
        } catch (Exception e) {
            Log.d(TAG, e.toString());
        } finally {
            if (out != null) {
                try {
                    out.close();
                    out = null;
                } catch (IOException e) {
                    Log.d(TAG, e.toString());
                }
            }
            if (in != null) {
                try {
                    in.close();
                    in = null;
                } catch (IOException e) {
                    Log.d(TAG, e.toString());
                }
            }
        }
        return dist;
    }

    @Override
    public boolean isNull(Object obj) {
        return obj == null;
    }

    @Override
    public boolean isNotNull(Object obj) {
        return obj != null;
    }

    @Override
    public boolean isNotAllEmpty(Object obj) {
        return !isNEmpty(obj);
    }

    @Override
    public boolean isNEmpty(Object obj) {
        return obj == null || isEmpty(obj);
    }

    @Override
    public boolean isNotEmpty(Object obj) {
        return !isEmpty(obj);
    }

    @Override
    public boolean isEmpty(Object obj) {
        boolean isEmpty = true;
        if (obj != null) {
            if (obj instanceof CharSequence) {
                // 字符串
                CharSequence tmp = (CharSequence) obj;
                isEmpty = tmp.length() == 0;
            } else if (obj instanceof Collection<?>) {
                // 集合
                Collection<?> collections = (Collection<?>) obj;
                isEmpty = collections.size() == 0;
            } else if (obj instanceof Map<?, ?>) {
                // Map
                Map<?, ?> map = (Map<?, ?>) obj;
                isEmpty = map.size() == 0;
            } else if (obj instanceof Object[]) {
                // 数组
                Object[] objarray = (Object[]) obj;
                isEmpty = objarray.length == 0;
            } else {
                // 其它类型对象统一为非空
                isEmpty = false;
            }
        }
        return isEmpty;
    }

    @Override
    public boolean containIndex(List<?> list, int position) {
        return isNotAllEmpty(list) && position < list.size() && position >= 0;
    }

    @Override
    public void close(Object closeObj) {
        if (closeObj != null) {
            try {
                if (closeObj instanceof Closeable) {
                    // IO 操作的流对象
                    ((Closeable) closeObj).close();
                } else if (closeObj instanceof Cursor) {
                    // 关闭Cursor
                    ((Cursor) closeObj).close();
                } else if (closeObj instanceof SQLiteClosable) {
                    // 关闭SQLite数据库相关引用
                    ((SQLiteClosable) closeObj).releaseReference();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void removeListNullValue(Object response) {
        if (response != null) {
            try {
                Field field = response.getClass().getDeclaredField("data");
                if (field == null) return;
                field.setAccessible(true);
                Object data = field.get(response);
                Log.d(TAG, "removeListNullValue1 type = " + field.getType().getName());
                if (data instanceof List) {
                    //data是个数组 第一层数据过滤
                    if (!isEmpty(data)) {
                        Log.d(TAG, "removeListNullValue1 before = " + data.toString());
                        ((List) (data)).removeAll(Collections.singleton(null));
                        Log.d(TAG, "removeListNullValue1 after = " + data.toString());
                    }
                } else {
                    //data是个对象，找到data里面的list并且将null替换掉
                    if (data != null) {
                        Field[] fields = field.getType().getDeclaredFields();
                        if (fields != null && fields.length > 0) {
                            for (int i = 0, len = fields.length; i < len; i++) {
                                if (fields[i] != null) {
                                    fields[i].setAccessible(true);
                                    Log.d(TAG, "removeListNullValue2 type = " + fields[i].getType().getName());
                                    if (fields[i].getType() == List.class) {
                                        Object obj = fields[i].get(data);
                                        if (obj instanceof List) {
                                            List<String> subListFieldNames = null;//列表里面的item带的列表的字段名
                                            //第二层数据过滤
                                            List list = (List) obj;
                                            if (!isEmpty(obj)) {
                                                Log.d(TAG, "removeListNullValue2 before = " + obj.toString());
                                                list.removeAll(Collections.singleton(null));
                                                Log.d(TAG, "removeListNullValue2 after = " + obj.toString());
                                            }
                                            //找到obj里面的列表字段名
                                            if (subListFieldNames == null) {
                                                //第一个元素的时候去找该元素里面的列表字段名，找一次就不用找了
                                                if (!isEmpty(list)) {
                                                    subListFieldNames = getObjectListFieldNames(list.get(0));
                                                }
                                            }
                                            if (!isEmpty(subListFieldNames)) {
                                                for (int j = 0, nameLength = subListFieldNames.size(); j < nameLength; j++) {
                                                    //第三层数据过滤
                                                    for (int k = 0; k < list.size(); k++) {
                                                        if (list.get(k) == null) continue;
                                                        Field subListField = list.get(k).getClass().getDeclaredField(subListFieldNames.get(j));
                                                        subListField.setAccessible(true);
                                                        Object subListObj = subListField.get(list.get(k));
                                                        if (subListObj instanceof List) {
                                                            if (!isEmpty(subListObj)) {
                                                                Log.d(TAG, "removeListNullValue3 before = " + subListObj.toString());
                                                                ((List) (subListObj)).removeAll(Collections.singleton(null));
                                                                Log.d(TAG, "removeListNullValue3 after = " + subListObj.toString());
                                                            }
                                                        }
                                                    }

                                                }
                                            }
                                        }

                                    }
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取obj里面的list字段名称
     *
     * @param obj
     * @return 字段名
     */
    private static List<String> getObjectListFieldNames(Object obj) {
        List<String> name = new ArrayList<>();
        if (obj != null) {
            Log.d(TAG, "getObjectListFieldNames type = " + obj.getClass().getName());
            Field[] fields = obj.getClass().getDeclaredFields();
            if (fields != null && fields.length > 0) {
                for (Field field : fields) {
                    field.setAccessible(true);
                    Log.d(TAG, "getObjectListFieldNames name = " + field.getName());
                    if (field.getType() == List.class) {
                        //找到列表
                        name.add(field.getName());
                        Log.d(TAG, "getObjectListFieldNames add name = " + field.getName());
                    }
                }
            }
        }
        return name;
    }

}
